package com.frikinet.gestorepub.web.spring.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.frikinet.gestorepub.model.Author;
import com.frikinet.gestorepub.model.Book;
import com.frikinet.gestorepub.model.Category;
import com.frikinet.gestorepub.model.Editor;
import com.frikinet.gestorepub.model.Serie;
import com.frikinet.gestorepub.model.WebUser;
import com.frikinet.gestorepub.web.spring.repositories.ModelDAO;
import com.google.appengine.api.users.User;

@Service
public class JDOPersistenceServiceImpl implements PersistenceService
{
	@Autowired
	private ModelDAO modelDAO;
	
	@Autowired
	private CacheService cacheService;	

	@Override
	public void saveBook(Book book)
	{
		modelDAO.persist(book);
		for(Author author: book.getAuthors())
		{
			saveAuthor(author);
		}
		for(Category category: book.getCategories())
		{
			saveCategory(category);
		}
		if(book.getSerie() != null)
		{
			saveSerie(book.getSerie());
		}
		if(book.getEditor() != null)
		{
			saveEditor(book.getEditor());
		}
		cacheService.put(book);
	}

	@Override
	public void saveAuthor(Author author)
	{
		if(cacheService.get(Author.class, author.getId()) == null)
		{
			if(modelDAO.get(Author.class, author.getId()) == null)
			{
				modelDAO.persist(author);
				cacheService.put(author);
			}
		}
	}

	@Override
	public void saveCategory(Category category)
	{
		if(cacheService.get(Category.class, category.getId()) == null)
		{
			if(modelDAO.get(Category.class, category.getId()) == null)
			{
				modelDAO.persist(category);
				cacheService.put(category);
			}
		}
	}

	@Override
	public void saveEditor(Editor editor)
	{
		if(cacheService.get(Editor.class, editor.getId()) == null)
		{
			if(modelDAO.get(Editor.class, editor.getId()) == null)
			{
				modelDAO.persist(editor);
				cacheService.put(editor);
			}
		}
	}

	@Override
	public void saveSerie(Serie serie)
	{
		if(cacheService.get(Serie.class, serie.getId()) == null)
		{
			if(modelDAO.get(Serie.class, serie.getId()) == null)
			{
				modelDAO.persist(serie);
				cacheService.put(serie);
			}
		}
	}
	
	@Override
	public void saveWebUser(WebUser user)
	{
		modelDAO.persist(user);
		cacheService.put(String.format("user-%s", user.getGoogleUser().getEmail()), user);
	}

	@Override
	public Book getBook(Long id)
	{
		Book book = cacheService.get(Book.class, id);
		if(book == null)
		{
			book = modelDAO.get(Book.class, id);
			if(book != null)
			{
				for(Long idAuthor: book.getAuthorKeys())
				{
					Author author = getAuthor(idAuthor);
					if(author != null)
						book.getAuthors().add(author);
				}
				for(Long idCategory: book.getCategoryKeys())
				{
					Category category = getCategory(idCategory);
					if(category != null)
						book.getCategories().add(category);
				}
				if(book.getSerieKey() != null)
				{
					Serie serie = getSerie(book.getSerieKey());
					if(serie != null)
						book.setSerie(serie);
				}
				if(book.getEditorKey() != null)
				{
					Editor editor = getEditor(book.getEditorKey());
					if(editor != null)
						book.setEditor(editor);
				}
			}
			cacheService.put(book);
		}
		return book;
	}

	@Override
	public Author getAuthor(Long id)
	{
		Author author = cacheService.get(Author.class, id);
		if(author == null)
		{
			author = modelDAO.get(Author.class, id);
			cacheService.put(author);
		}
		return author;
	}

	@Override
	public Category getCategory(Long id)
	{
		Category category = cacheService.get(Category.class, id);
		if(category == null)
		{
			category = modelDAO.get(Category.class, id);
			cacheService.put(category);
		}
		return category;
	}

	@Override
	public Editor getEditor(Long id)
	{
		Editor editor = cacheService.get(Editor.class, id);
		if(editor == null)
		{
			editor = modelDAO.get(Editor.class, id);
			cacheService.put(editor);
		}
		return editor;
	}

	@Override
	public Serie getSerie(Long id)
	{
		Serie editor = cacheService.get(Serie.class, id);
		if(editor == null)
		{
			editor = modelDAO.get(Serie.class, id);
			cacheService.put(editor);
		}
		return editor;
	}

	@Override
	public WebUser getWebUser(User user)
	{
		WebUser webUser = (WebUser)cacheService.get(String.format("user-%s", user.getEmail()));
		if(webUser == null)
		{
			webUser = modelDAO.getUniqueQuery(WebUser.class, "googleUser", user);
			if(webUser == null)
			{
				webUser = new WebUser();
				webUser.setGoogleUser(user);
				saveWebUser(webUser);
			}
		}
		return webUser;
	}
}
